/**
 *
 * © Bahadir Zeren 2011
 * bzeren@gmail.com
 * No warranties, express or implied, are made for this program.
 *
 */
package org.baatar.opt.genetic.set.util;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import org.baatar.opt.genetic.set.meta.DataSet;
import org.baatar.util.XMLReader;
import org.baatar.util.XMLWriter;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 
 * 
 * @author B_ZEREN
 */
public class XMLUtil {

    public static DataSet readSetOptimizationInputDataFromXML(String inputXmlFileName) throws Exception {

        final DataSet dataSet = new DataSet();

        DefaultHandler defaultHandler = new DefaultHandler() {

            private boolean chars = false;

            private int lastColumnCost = 0;
            private double lastColumnQuality = 0.0;
            private int lastLayoverCost = 0;

            @Override
            public void startDocument(){
            }

            @Override
            public void endDocument() throws SAXException {
            }

            @Override
            public void startElement(String uri,
                                        String localName,
                                        String qName,
                                        Attributes attributes) {
                chars = false;
                if (qName.equals("ds")) {
                } else
                    if (qName.equals("rl")) {
                        dataSet.setRowsArray(Integer.valueOf(attributes.getValue("numOfRows")));
                    } else
                        if (qName.equals("cl")) {
                            dataSet.setColsArray(Integer.valueOf(attributes.getValue("numOfCols")));
                        } else
                            if (qName.equals("r")) {
                                dataSet.addRow(Integer.valueOf(attributes.getValue("c")),
                                                attributes.getValue("i"));
                            } else
                                if (qName.equals("c")) {
                                    lastColumnCost = Integer.valueOf(attributes.getValue("c"));
                                    lastColumnQuality = Double.valueOf(attributes.getValue("q"));
                                    lastLayoverCost = Integer.valueOf(attributes.getValue("lc"));
                                    chars = true;
                                }
            }

            @Override
            public void endElement(String uri, String localName, String qName) {
                chars = false;
                if (qName.equals("ds")){
                } else
                    if (qName.equals("rl")) {
                    } else
                        if (qName.equals("cl")) {
                        } else
                            if (qName.equals("r")) {
                            } else
                                if (qName.equals("c")) {
                                }
            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                if (chars) {
                    String tagContent = String.valueOf(ch, start, length);
                    dataSet.addColumn(lastColumnCost, lastLayoverCost, lastColumnQuality, tagContent);
                }
            }

            @Override
            public void processingInstruction (String target, String data) throws SAXException {
            }
        };

        XMLReader.readXML(inputXmlFileName, defaultHandler);

        return dataSet;
    }

    public static void convertPairXMLtoSetXML(String inputXmlFileName,
                                String outputXmlFileName) throws XMLStreamException, FileNotFoundException, Exception {

        final XMLWriter xmlWriter = new XMLWriter();
        xmlWriter.initializeXMLFile(outputXmlFileName);

        DefaultHandler defaultHandler = new DefaultHandler() {
            private boolean chars = false;

            @Override
            public void startDocument(){
            }

            @Override
            public void endDocument() throws SAXException {
            }

            @Override
            public void startElement(String uri,
                                        String localName,
                                        String qName,
                                        Attributes attributes) {
                try {
                    chars = false;
                    if (qName.equals("generatedPairs")) {
                        xmlWriter.startTag(uri, localName, "ds", null);
                        xmlWriter.writeLineEnd();
                        xmlWriter.increaseIndent();
                    } else
                        if (qName.equals("flightList")) {
                            xmlWriter.startTag(uri, localName, "rl", null);
                            xmlWriter.writeLineEnd();
                            xmlWriter.increaseIndent();
                        } else
                            if (qName.equals("pairList")) {
                                xmlWriter.startTag(uri, localName, "cl", null);
                                xmlWriter.writeLineEnd();
                                xmlWriter.increaseIndent();
                            } else
                                if (qName.equals("flight")) {
                                    String index = attributes.getValue("index");
                                    String cost = attributes.getValue("cost");
                                    String info = attributes.getValue("fcode") +
                                                    "_" +
                                                    attributes.getValue("depap") +
                                                    "-" +
                                                    attributes.getValue("arrap") +
                                                    "_" +
                                                    attributes.getValue("dept").substring(0, 16);
                                    ArrayList<Attribute> attributesList = new ArrayList<Attribute>();
                                    attributesList.add(xmlWriter.generateAttribute("x", index));
                                    attributesList.add(xmlWriter.generateAttribute("c", cost));
                                    attributesList.add(xmlWriter.generateAttribute("i", info));
                                    xmlWriter.startTagWithAttributeList(uri, localName, "r", attributesList);
                                }
                                else
                                    if (qName.equals("pair")) {
                                        String index = attributes.getValue("index");
                                        String cost = attributes.getValue("cost");
                                        String ratio = attributes.getValue("ratio");
                                        if (ratio.length() > 10)
                                            ratio = ratio.substring(0, 10);
                                        ArrayList<Attribute> attributesList = new ArrayList<Attribute>();
                                        attributesList.add(xmlWriter.generateAttribute("x", index));
                                        attributesList.add(xmlWriter.generateAttribute("c", cost));
                                        attributesList.add(xmlWriter.generateAttribute("q", ratio));
                                        xmlWriter.startTagWithAttributeList(uri, localName, "c", attributesList);
                                        chars = true;
                                    }
                } catch (XMLStreamException ex) {
                    ex.printStackTrace();
                }
            }

            @Override
            public void endElement(String uri, String localName, String qName) {
                chars = false;
                try {
                    if (qName.equals("generatedPairs")) {
                        xmlWriter.decreaseIndent();
                        xmlWriter.writeIndent();
                        xmlWriter.endTag(uri, localName, "ds");
                    } else
                        if (qName.equals("flightList")) {
                            xmlWriter.decreaseIndent();
                            xmlWriter.writeIndent();
                            xmlWriter.endTag(uri, localName, "rl");
                        } else
                            if (qName.equals("pairList")) {
                                xmlWriter.decreaseIndent();
                                xmlWriter.writeIndent();
                                xmlWriter.endTag(uri, localName, "cl");
                            } else
                                if (qName.equals("flight"))
                                    xmlWriter.endTag(uri, localName, "r");
                                else
                                    if (qName.equals("pair"))
                                        xmlWriter.endTag(uri, localName, "c");
                } catch (XMLStreamException ex) {
                    ex.printStackTrace();
                }
            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                try {
                    if (chars) {
                        String tagContent = String.valueOf(ch, start, length);
                        xmlWriter.addCharacters(tagContent.trim());
                    }
                } catch (XMLStreamException ex) {
                    ex.printStackTrace();
                }
            }

            @Override
            public void processingInstruction (String target, String data) throws SAXException {
            }
        };

        XMLReader.readXML(inputXmlFileName, defaultHandler);

        xmlWriter.getOutputStream();
    }
}
